package cn.iocoder.yudao.module.data.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Pair;
import cn.iocoder.yudao.module.data.constants.KLineType;
import cn.iocoder.yudao.module.data.core.StockPattern;
import cn.iocoder.yudao.module.data.entity.dto.StockKLineReqDTO;
import cn.iocoder.yudao.module.data.entity.dto.StockKLineRespDTO;
import cn.iocoder.yudao.module.data.entity.dto.StockTrendsReqDTO;
import cn.iocoder.yudao.module.data.entity.dto.StockTrendsRespDTO;
import cn.iocoder.yudao.module.data.third.eastMoney.request.EastMoneyStockFenShiRequest;
import cn.iocoder.yudao.module.data.third.eastMoney.request.EastMoneyStockHistoryKLineRequest;
import cn.iocoder.yudao.module.data.third.eastMoney.response.EastMoneyStockFenShiResponse;
import cn.iocoder.yudao.module.data.third.eastMoney.response.EastMoneyStockHistoryKLineResponse;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 东方财富
 * </p>
 *
 * @author pokbrin
 * @date 2023-07-20 15:25
 */
@Slf4j
@Service
public class EastMoneyServiceImpl implements IEastMoneyService {


    private final static Map<StockPattern.StockType, Function<String, String>> CODE_CONVERT = Maps.newHashMapWithExpectedSize(2);

    private final static Map<KLineType, String> K_LINE_MAP = Maps.newHashMapWithExpectedSize(10);

    static {
        for (StockPattern.StockType sh : StockPattern.StockType.SHS) {
            CODE_CONVERT.put(sh, s -> "1." + s);
        }
        for (StockPattern.StockType sh : StockPattern.StockType.SZS) {
            CODE_CONVERT.put(sh, s -> "0." + s);
        }
        K_LINE_MAP.put(KLineType.K_1_M, "1");
        K_LINE_MAP.put(KLineType.K_5_M, "5");
        K_LINE_MAP.put(KLineType.K_15_M, "15");
        K_LINE_MAP.put(KLineType.K_30_M, "30");
        K_LINE_MAP.put(KLineType.K_60_M, "60");
        K_LINE_MAP.put(KLineType.K_DAY, "101");
        K_LINE_MAP.put(KLineType.K_WEEK, "102");
        K_LINE_MAP.put(KLineType.K_MONTH, "103");
        K_LINE_MAP.put(KLineType.K_QUARTER, "104");
        K_LINE_MAP.put(KLineType.K_YEAR, "105");
    }

    @Override
    public StockTrendsRespDTO stockTrends(StockTrendsReqDTO dto) {
        String code = dto.getCode();
        StockPattern.MatherResult match = StockPattern.match(code);
        String afterCode = match.getAfterCode();
        StockPattern.StockType stockType = match.getStockType();
        EastMoneyStockFenShiResponse easyMoneyFenShiResp = EastMoneyStockFenShiRequest.builder()
                .fields1("f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13")
                .fields2("f51,f52,f53,f54,f55,f56,f57,f58")
                .secid(CODE_CONVERT.get(stockType).apply(afterCode))
                .ndays(dto.getDays())
                .build()
                .doGet();
        EastMoneyStockFenShiResponse.InnerData data = easyMoneyFenShiResp.getData();
        EastMoneyStockFenShiResponse.Holder holder = new EastMoneyStockFenShiResponse.Holder(easyMoneyFenShiResp);
        List<EastMoneyStockFenShiResponse.TrendVO> trendVOS = holder.getTrendVOS();
        StockTrendsRespDTO respDTO = new StockTrendsRespDTO();
        List<StockTrendsRespDTO.TrendsDetail> minuteDetails = IntStream.range(0, trendVOS.size()).mapToObj(index -> {
            EastMoneyStockFenShiResponse.TrendVO t = trendVOS.get(index);
            StockTrendsRespDTO.TrendsDetail detail = new StockTrendsRespDTO.TrendsDetail();
            EastMoneyStockFenShiResponse.TrendVO pre = trendVOS.get(Math.max(index - 1, 0));
            detail.setAvgPrice(t.getAvgPrice());
            detail.setCode(data.getCode());
            detail.setName(data.getName());
            detail.setPreClose(pre.getPrice());
            detail.setOpen(t.getOpen());
            detail.setPrice(t.getPrice());
            detail.setHigh(t.getHigh());
            detail.setLow(t.getLow());
            detail.setVol(t.getVol());
            detail.setAmount(t.getAmount());
            detail.setDate(t.getTrendTime().toLocalDate());
            detail.setTime(t.getTrendTime().toLocalTime());
            BigDecimal riseFall = t.getPrice().subtract(pre.getPrice());
            return detail;
        }).collect(Collectors.toList());
        respDTO.setTrends(minuteDetails);
        respDTO.setCode(data.getCode());
        respDTO.setName(data.getName());
        respDTO.setPreClose(data.getPreClose());
        respDTO.setOpen(holder.getOpen());
        respDTO.setPrice(holder.getClose());
        respDTO.setHigh(holder.getHigh());
        respDTO.setLow(holder.getLow());
        Pair<Integer, BigDecimal> volAmount = holder.getVolAmount();
        respDTO.setVol(volAmount.getKey());
        respDTO.setAmount(volAmount.getValue());
        Pair<LocalDate, LocalTime> time = holder.getLocalDateTime();
        respDTO.setDate(time.getKey());
        return respDTO;
    }

    @Override
    public StockKLineRespDTO stockKLine(StockKLineReqDTO dto) {
        StockPattern.MatherResult match = StockPattern.match(dto.getCode());
        EastMoneyStockHistoryKLineResponse response = EastMoneyStockHistoryKLineRequest.builder()
                .secid(CODE_CONVERT.get(match.getStockType()).apply(match.getAfterCode()))
                .beg(LocalDateTimeUtil.format(dto.getStartDate(), DatePattern.PURE_DATE_FORMATTER))
                .end(LocalDateTimeUtil.format(dto.getEndDate(), DatePattern.PURE_DATE_FORMATTER))
                .klt(K_LINE_MAP.get(dto.getKLineType()))
                .build()
                .doGet();
        //TODO 待完成

        return null;
    }
}
